package com.zyd.blog.homeart.util;

import com.alibaba.fastjson.JSON;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author ZuRongTang
 * @Date 2019/8/23
 **/


public class HttpClientUtil {

    private static Logger log = LoggerFactory.getLogger(HttpClientUtil.class);

    private static int CONNECT_TIME_OUT = 15 * 1000;

    private static int READ_TIME_OUT = 30 * 1000;//40秒

    private HttpClientUtil() {
    }


    public static String get(String reqURL) {
        log.info("get() 请求  reqURL: {} ", reqURL);
        CloseableHttpClient httpClient = null;
        HttpGet httpGet;
        String responseResult = null; // 响应内容
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.createDefault();
            httpGet = new HttpGet(reqURL);
            httpGet.setConfig(doRequestConfig());
            response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity(); // 获取响应实体
            if (null != entity) {
                responseResult = EntityUtils.toString(entity, "UTF-8");
                EntityUtils.consume(entity);
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            log.error("该异常通常是协议错误", e);
        } catch (ParseException e) {
            e.printStackTrace();
            log.error("解析异常", e);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("该异常通常是网络原因引起的", e);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("异常信息：", e);
        } finally {
            closeHttp(response, httpClient);
        }
        return responseResult;
    }

    /**
     * 发送post 请求（json格式）
     *
     * @return result
     * @
     * @
     */
    public static String postJson(String reqURL, Map<String, String> map) {

        CloseableHttpClient httpClient = null;
        HttpPost httpPost;
        String responseResult = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.createDefault();
            httpPost = new HttpPost(reqURL);
            httpPost.setConfig(doRequestConfig());
            httpPost.setHeader(HTTP.CONTENT_TYPE, "application/json");
            String s = JSON.toJSONString(map);
            StringEntity entity = new StringEntity(s, "UTF-8");
            entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_ENCODING, "UTF-8"));
            entity.setContentType("application/json");

            httpPost.setEntity(entity);
            response = httpClient.execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            if (httpEntity != null) {
                responseResult = EntityUtils.toString(httpEntity, "UTF-8");
                EntityUtils.consume(httpEntity);
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            log.error("该异常通常是协议错误", e);
        } catch (ParseException e) {
            e.printStackTrace();
            log.error("解析异常", e);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("该异常通常是网络原因引起的", e);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("异常信息：", e);
        } finally {
            closeHttp(response, httpClient);
        }
        return responseResult;
    }

    /**
     * 发送post 请求  (x-www-form-urlencoded)
     */
    public static String postForm(String reqURL, Map<String, String> param) {
        CloseableHttpClient httpClient = null;
        HttpPost httpPost;
        String responseResult = null;
        CloseableHttpResponse response = null;
        try {
            httpClient = HttpClients.createDefault();
            httpPost = new HttpPost(reqURL);
            httpPost.setConfig(doRequestConfig());
            httpPost.setHeader(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded");

            List<NameValuePair> formParams = new ArrayList<>(); // 创建参数队列
            if (param != null && param.size() > 0) {
                for (Map.Entry<String, String> entry : param.entrySet()) {
                    formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));

                }
            }

            httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
            response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            if (null != entity) {
                responseResult = EntityUtils.toString(entity, "UTF-8");
                EntityUtils.consume(entity);
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            log.error("该异常通常是协议错误", e);
        } catch (ParseException e) {
            e.printStackTrace();
            log.error("解析异常", e);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("该异常通常是网络原因引起的", e);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("异常信息：", e);
        } finally {
            closeHttp(response, httpClient);
        }
        return responseResult;
    }

    private static void closeHttp(CloseableHttpResponse response, CloseableHttpClient httpClient) {
        try {
            if (response != null) {
                response.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (httpClient != null) {
                httpClient.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static String httpPostRequest2(String url, List<MultipartFile> multipartFiles, List<String> fileParName,
                                          Map<String, Object> params, int timeout) {
        Map<String, String> resultMap = new HashMap<String, String>();
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String result = "";
        try {
            HttpPost httpPost = new HttpPost(url);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setCharset(Charset.forName("UTF-8"));
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            String fileName = "12321";
            MultipartFile multipartFile = null;
            for (int i = 0; i <multipartFiles.size() ; i++) {
                multipartFile = multipartFiles.get(i);
                fileName = multipartFile.getOriginalFilename();
                builder.addBinaryBody(fileParName.get(i), multipartFile.getInputStream(), ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
            }
            //决中文乱码
            ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8);
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                if(entry.getValue() == null)
                    continue;
                // 类似浏览器表单提交，对应input的name和value
                builder.addTextBody(entry.getKey(), entry.getValue().toString(), contentType);
            }
            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);// 执行提交

            // 设置连接超时时间
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout)
                    .setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).build();
            httpPost.setConfig(requestConfig);

            HttpEntity responseEntity = response.getEntity();
            resultMap.put("scode", String.valueOf(response.getStatusLine().getStatusCode()));
            resultMap.put("data", "");
            if (responseEntity != null) {
                // 将响应内容转换为字符串
                result = EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
                resultMap.put("data", result);
            }
        } catch (Exception e) {
            resultMap.put("scode", "error");
            resultMap.put("data", "HTTP请求出现异常: " + e.getMessage());

            Writer w = new StringWriter();
            e.printStackTrace(new PrintWriter(w));
            log.error("HTTP请求出现异常: " + w.toString());
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    private static RequestConfig doRequestConfig() {
        return RequestConfig.custom()//
                .setConnectTimeout(CONNECT_TIME_OUT)// 连接一个url的连接等待时间
                .setConnectionRequestTimeout(CONNECT_TIME_OUT)//
                .setSocketTimeout(READ_TIME_OUT)// 读取数据超时
                .build();
    }



}
